/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package earthdawnnet.server;

import earthdawnnet.events.client.ClientsChangedEvent;
import earthdawnnet.events.client.KickedEvent;
import earthdawnnet.events.client.LoginAcceptedEvent;
import earthdawnnet.events.client.NewLineEvent;
import earthdawnnet.events.client.ServerShutdownEvent;
import earthdawnnet.util.Chat;
import earthdawnnet.util.DiceCup;
import earthdawnnet.util.Roll;
import java.io.IOException;
import java.util.Set;
import java.util.concurrent.ConcurrentMap;
import java.util.concurrent.ConcurrentSkipListMap;
import java.util.logging.Level;
import java.util.logging.Logger;

/**
 *
 * @author Andreas Franek
 */
public class EarthdawnServer implements IEarthdawnServer
{
    private ConcurrentMap<Integer, String> names = new ConcurrentSkipListMap<Integer, String>();
    private Chat chat;
    
    // <editor-fold defaultstate="collapsed" desc="Start/stop mechanisms">
    private Server connection;
    public EarthdawnServer()
    {
        chat = new Chat();
        try
        {
            this.connection = new Server(this);
        } catch (IOException ex)
        {
            Logger.getLogger(EarthdawnServer.class.getName()).log(Level.SEVERE, null, ex);
            System.exit(0);
        }
    }
    
    public final void start()
    {
        connection.start();
        ServerView.startup(this);
    }
    
    public void stop()
    {
        connection.broadcast(new ServerShutdownEvent());
        connection.close();
    }
    
    public static void main(String[] args)
    {
        EarthdawnServer eds = new EarthdawnServer();
        eds.start();
    }
    // </editor-fold>

    // <editor-fold defaultstate="collapsed" desc="Event Handling">
    public void login(int sender, String name)
    {
        
        names.put(sender, name);
        connection.send(sender, new LoginAcceptedEvent(chat.getChatLines()));
        clientsChanged();
    }

    public void logout(int id)
    {
        //System.out.println("Client: " + id + " logged out.");
        names.remove(id);
        connection.remove(id);
        clientsChanged();
    }

    public void changeName(int sender, String name)
    {
        names.put(sender, name);
        clientsChanged();
    }

    public void addLine(int sender, String line)
    {
        String chatLine = names.get(sender) + ": " + line;
        addLine(chatLine);
    }
    
    private void addLine(String line)
    {
        chat.add(line);
        connection.broadcast(new NewLineEvent(line));
    }

    public void roll(int sender, int step, boolean rollAgainst, int against)
    {
        Roll result = DiceCup.roll(step, rollAgainst, against);
        addLine(names.get(sender) + " " + result.getDescription());
    }

    private void clientsChanged()
    {
        Integer[] tmp = names.keySet().toArray(new Integer[0]);
        int[] ids = new int[tmp.length];
        for(int i = 0; i < ids.length; i++)
        {
            ids[i] = tmp[i];
        }
        connection.broadcast(new ClientsChangedEvent(names.values().toArray(new String[0]), ids));
    }

    public void kick(int toBeKicked)
    {
        connection.send(toBeKicked, new NewLineEvent("You were kicked"));
        connection.send(toBeKicked, new KickedEvent());
        logout(toBeKicked);
    }

    public void whisper(int sender, int receiver, String line)
    {
        connection.send(receiver, new NewLineEvent(names.get(sender) + " whispered: " + line));
    }
    // </editor-fold>
}
